# 筹码图分析
# 包括下方的文字信息

import time
import cv2
import numpy as np
import pytesseract
# import re


# 可能会有多个匹配, 返回所有匹配先
def find_all_matches(screen_img, template_img, threshold):
    """获取所有符合阈值的匹配结果，返回列表[(x, y, w, h, 匹配度)]"""
    # # 预处理（使用之前优化的预处理函数）
    # screen_processed = preprocess_image(screen_img)
    # template_processed = preprocess_image(template_img, is_template=True)
    h, w = template_img.shape[:2]
    
    if h == 0 or w == 0:
        return []
    
    # 0. 校验输入截图有效性
    if screen_img is None or screen_img.size == 0:
        raise ValueError("输入的股票软件截图为空")
    
    window_h,window_w = screen_img.shape[:2]
    if(window_h<h or window_w<w):
        print("!!!!    ERR 28 截图尺寸小于模板尺寸")
        return []
    
    # 执行模板匹配并获取匹配度矩阵
    result = cv2.matchTemplate(
        screen_img, 
        template_img, 
        cv2.TM_CCOEFF_NORMED
    )
    # 找到所有超过阈值的位置
    locations = np.where(result >= threshold)
    matches = []
    
    # 遍历所有匹配位置，记录坐标和匹配度
    for y, x in zip(locations[0], locations[1]):
        match_value = result[y, x]  # 该位置的匹配度（0-1）
        matches.append((x, y, w, h, match_value))  # 存储x坐标、y坐标、宽、高、匹配度
    return matches

def percent_to_float(percent_str):
    """将带百分号的字符串转换为浮点数"""
    # 移除字符串中的百分号
    num_str = percent_str.strip('%')
    # 转换为浮点数
    try:
        return float(num_str)
    except ValueError:
        raise ValueError(f"无法将 '{percent_str}' 转换为浮点数")
    
# 找 模板匹配
def find_template_position(screen_img, template_img, threshold=0.85):
    """
    在屏幕截图中查找模板位置
    :param screen_img: 全屏截图（BGR格式）
    :param template_img: 模板图片（BGR格式）
    :param threshold: 匹配阈值（0-1，越高越严格） 数值为0.8时,还是会有错误, 比如需匹配0.00%,匹配到的却是0.05%
    :return: 匹配区域的左上角坐标(x, y)，若未找到返回None
    """
    # # 获取模板尺寸
    # h, w = template_img.shape[:2]
    
    # # 执行模板匹配
    # result = cv2.matchTemplate(screen_img, template_img, cv2.TM_CCOEFF_NORMED)
    
    # # 查找匹配度超过阈值的位置
    # locations = np.where(result >= threshold)

    # # 取匹配度最高的位置
    # if len(locations[0]) > 0:
    #     # 找到最大匹配值的索引
    #     print("#多个匹配的情况")
    #     max_idx = np.argmax(result)
    #     h_idx, w_idx = np.unravel_index(max_idx, result.shape)
    #     return (w_idx, h_idx, w, h)  # (x, y, 宽, 高)

    all_matches  = find_all_matches(screen_img, template_img,threshold)
    if not all_matches:
        return None  # 无匹配结果
    # 按X坐标升序排序（X越小越靠左），取第一个
    # 若X相同，可选匹配度最高的
    all_matches.sort(key=lambda m: (m[0], -m[1]))  # 优先按X排序，再按y排序 找到左上角的一个叉按钮
    rightmost = all_matches[0]
    return (rightmost[0], rightmost[1], rightmost[2], rightmost[3])  # 返回(x, y, w, h)
    # # 取第一个匹配位置（最相似的）
    # for pt in zip(*locations[::-1]):  # pt为左上角坐标
    #     print("#只有一个匹配的情况")
    #     return (pt[0], pt[1], w, h)  # 返回(x, y, 宽度, 高度)
    
    # return None  # 未找到匹配区域


def chip_infomation_extraction(screen_shot_img):
    # return 返回文字与数值的键值对

    # # DEBUG: 保存所输入的图像.
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction.png", screen_shot_img)

    # 结果数组:
    _result = []

    # 1. 取最左侧, 亮度大于(7,7,7)的, 有一个通道大于7就算是了.
    height, width  = screen_shot_img.shape[:2]
    y_first_pos = 0
    y_last_pos = 0
    for y in range(height):
        r,g,b = screen_shot_img[y, 0]
        if r>7 or g>7 or b>7:
            if 0 == y_first_pos:
                y_first_pos = y
            y_last_pos = y
    
    # 2. 裁剪出筹码图:
    image_chip_chart = screen_shot_img[y_first_pos:y_last_pos, :]
    # print("# 26 height:",height,"\twidth:",width)
    # # DEBUG: 保存所输入的图像.
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction_2.png", image_chip_chart)
    
    # # 3 输出黑白影像, 以调试对于亮度的判断是否正确.
    # height_2, width_2  = image_chip_chart.shape[:2]
    # for x in range(width_2):
    #     for y in range(height_2):
    #         r,g,b = image_chip_chart[y, x]
    #         if r>7 or g>7 or b>7:
    #             image_chip_chart[y, x] = [128,88,88]
    #         else:
    #             image_chip_chart[y, x] = [0,0,0]
    # # DEBUG: 保存所输入的图像.
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction_3.png", image_chip_chart)

    # 4. 取像素点数目:
    time_129 = time.time()
    height_2, width_2  = image_chip_chart.shape[:2]
    count_number_of_available_pixels = 0
    for y in range(height_2):
        for x in range(width_2):
            r,g,b = image_chip_chart[y, x]
            if r>7 or g>7 or b>7:
                count_number_of_available_pixels += 1
                # image_chip_chart[y, x] = [128,88,88]
            else:
                break
    # # DEBUG: 保存所输入的图像.
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction_3.png", image_chip_chart)
    time_142 = time.time()
    # print("# 143 耗时:",time_142-time_129)

    # print("# 133 筹码有效像素点数目:",count_number_of_available_pixels)
    _result.append(("筹码有效像素点数目:",count_number_of_available_pixels))


    # 文字信息部分:
    image_chip_word_info = screen_shot_img[y_last_pos:, :]
    # 加载模板:
    template_chip_word_info_profit_ratio = cv2.imread("eastmoney desktop software picture/chip_profit_ratio.png")
    template_chip_word_info_concentration = cv2.imread("eastmoney desktop software picture/chip_concentration.png")
    
    # 查找模板位置
    target_pos = find_template_position(image_chip_word_info, template_chip_word_info_profit_ratio)
    # print("# 141 模板位置:",target_pos)
    if target_pos is None:
        print("!!!!    ERR 142 没取得模板位置")
        return _result
    # 根据模板位置, 取目标文件的所在区域:
    image_target_word_profit_ratio = image_chip_word_info[target_pos[1]:target_pos[1]+target_pos[3], target_pos[0]+target_pos[2]:]
                
    # # DEBUG: 保存所输入的图像.
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction_4_profit_ratio.png", image_target_word_profit_ratio)

    # BEGIN 找空列:
    time_165 = time.time()
    profit_ratio_1_height,profit_ratio_1_width = image_target_word_profit_ratio.shape[:2]
    profit_ratio_state = 0 # 0 从一开始, 是几列全黑  1: 之后是一个进度条  2: 之后又是几列全黑
    split_x = 0 # 裁剪位置
    for x in range(profit_ratio_1_width):
        have_some_thing = False
        for y in range(profit_ratio_1_height):
            r,g,b = image_target_word_profit_ratio[y, x]
            if r>7 or g>7 or b>7:
                have_some_thing=True
                break
        if(0 == profit_ratio_state and have_some_thing):
            profit_ratio_state = 1 # 到了进度条的位置
        if(1 == profit_ratio_state and not have_some_thing):
            profit_ratio_state = 2 # 过了进度条
        if(2==profit_ratio_state):
            split_x = x
            break
    image_target_word_profit_ratio = image_target_word_profit_ratio[:, split_x:]
    time_184=   time.time()
    # print("# 185 耗时:",time_184-time_165)
    # # DEBUG: 保存所输入的图像.
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction_4_profit_ratio_2.png", image_target_word_profit_ratio)
    # END 找空列

    # 取出文字:
    custom_config = r'--oem 3 --psm 6 -c tessedit_char_whitelist=0123456789.%'
    text_profit_ratio = pytesseract.image_to_string(image_target_word_profit_ratio,config=custom_config) # 
    # print("# 166 获取的文字:",text_profit_ratio)
    text_profit_ratio=text_profit_ratio.strip(' \n\r.')

    # print("# 154 获取的文字:",text_profit_ratio)
    if(''==text_profit_ratio):return []
    _result.append(("获利比率",percent_to_float(text_profit_ratio)))
    # if target_pos:
    #     x, y, w, h = target_pos
    #     print(f"# 142 找到目标区域：({x}, {y})，尺寸：{w}×{h}")
    #     # 4. 基于模板位置推算K线区域（根据实际界面调整偏移量）
    #     # kline_x = x - 50  # 向左偏移50像素
    #     # kline_y = y + h + 20  # 向下偏移（模板高度+20像素）

    # 查找模板的位置  集中度
    target_pos = find_template_position(image_chip_word_info, template_chip_word_info_concentration)
    if target_pos is None:
        print("!!!!    ERR 179 没取得模板位置")
    # 根据模板位置, 取目标文件的所在区域:
    image_target_word_concentration = image_chip_word_info[target_pos[1]:target_pos[1]+target_pos[3], target_pos[0]+target_pos[2]:]
    # cv2.imwrite(f"out_test_screen_shot_clip_chip_infomation_extraction_5_concentration.png", image_target_word_concentration)
    # 取出文字:
    text_concentration = pytesseract.image_to_string(image_target_word_concentration,config=custom_config)
    # print("# 184 获取的文字:",text_concentration)
    text_concentration=text_concentration.strip(' \n).')
    # 清理结果：移除多余字符，保留数字、小数点和百分号
    # cleaned = re.sub(r'[^0-9.]%$', '', text_concentration)
    # print("#189 cleaned:",cleaned)
    # print("# 186 获取的文字:",text_concentration)
    _result.append(("筹码集中度",percent_to_float(text_concentration)))


                


    return _result